home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / web2ctex / ctex / c / text < prev   
Encoding:
Text File  |  1990-07-27  |  16.9 KB  |  591 lines

  1. #ifdef RISC_OS
  2. /* c.armtxt --- aka c.textwindow
  3.    ---Tiggr & Graham
  4.  
  5.  ******************************************************************************
  6.  
  7.     Example: 80 * 24 screen, 200 row buffer, with history, buffer NOT full
  8.  
  9.           inclusive pointers              exclusive pointers
  10.                              +----------+
  11.                    buf_start |          |
  12.                              |          |
  13.                              |          |
  14.                              +----------+
  15.     buf_end - 24 = scr_start |          |
  16.                              |  screen  |
  17.                              |          |
  18.                              +----------+
  19.                              |          | buf_end
  20.                              |          |
  21.                              |          |
  22.                              +----------+
  23.                                           buf_num_rows = 200
  24.  
  25.  ******************************************************************************
  26.  
  27.         Example: 80 * 24 screen, 200 row buffer, buffer is FULL
  28.  
  29.  
  30.           inclusive pointers              exclusive pointers
  31.                              +----------+
  32.                              |          |
  33.                              |          |                   decreasing
  34.                              |          |                   rownumbers
  35.                              +----------+                       ^
  36.     buf_end - 24 = scr_start |          |                       |
  37.                              |  screen  |                       |
  38.                              |          |                       |
  39.                              +----------+                         
  40.          buf_end = buf_start |          | buf_end
  41.                              |          |
  42.                              |          |
  43.                              +----------+
  44.                                           buf_num_rows = 200
  45.  
  46. ******************************************************************************/
  47.  
  48. typedef enum {               /* event types */
  49.   wimp_ENULL,                /* null event */
  50.   wimp_EREDRAW,              /* redraw event */
  51.   wimp_EOPEN,
  52.   wimp_ECLOSE,
  53.   wimp_EPTRLEAVE,
  54.   wimp_EPTRENTER,
  55.   wimp_EBUT,                 /* mouse button change */
  56.   wimp_EUSERDRAG,
  57.   wimp_EKEY,
  58.   wimp_EMENU,
  59.   wimp_ESCROLL,
  60.   wimp_ELOSECARET,
  61.   wimp_EGAINCARET,
  62.   wimp_ESEND = 17,        /* send message, don't worry if it doesn't arrive */
  63.   wimp_ESENDWANTACK = 18, /* send message, return ack if not acknowledged */
  64.   wimp_EACK = 19          /* acknowledge receipt of message. */
  65. } wimp_etype;
  66.  
  67. typedef enum {               /* event type masks */
  68.   wimp_EMNULL     = 1 << wimp_ENULL,
  69.   wimp_EMREDRAW   = 1 << wimp_EREDRAW,
  70.   wimp_EMOPEN     = 1 << wimp_EOPEN,
  71.   wimp_EMCLOSE    = 1 << wimp_ECLOSE,
  72.   wimp_EMPTRLEAVE = 1 << wimp_EPTRLEAVE,
  73.   wimp_EMPTRENTER = 1 << wimp_EPTRENTER,
  74.   wimp_EMBUT      = 1 << wimp_EBUT,
  75.   wimp_EMUSERDRAG = 1 << wimp_EUSERDRAG,
  76.   wimp_EMKEY      = 1 << wimp_EKEY,
  77.   wimp_EMMENU     = 1 << wimp_EMENU,
  78.   wimp_EMSCROLL   = 1 << wimp_ESCROLL
  79. } wimp_emask;
  80.  
  81. #define ARTHUR_NEW_NAMES
  82.  
  83. #include <Arthur.h>
  84. #include <stdlib.h>
  85. #include <stdio.h>
  86. #include <string.h>
  87. #include <signal.h>
  88.  
  89. /* no #ifdefs... */
  90. #define TRUE (0==0)
  91. #define FALSE (0!=0)
  92.  
  93. /*****************************************************************************/
  94.  
  95. static int MODULO (int a, int b)
  96. {
  97.    return ((a + b) % b);
  98.  
  99.    if (a >= 0) return a%b;
  100.    return (b + (a%b))%b;
  101. } /* MODULO */
  102.  
  103. #ifdef NEVER
  104. #define MODULO(a, b)     ((a) >= 0 ? ((a) % (b)) : (((b) + ((a) % (b))) % (b)))
  105. #endif
  106.  
  107. #define ROW(r)            MODULO ((r), buf_num_rows)
  108. #define SCREEN_START      ROW (buf_end - scr_num_rows)
  109. #define BUFFER_ROW(log)   ROW (log + buf_start)
  110. #define SCREEN(col, row)  buffer[ROW(SCREEN_START + (row)) * num_cols + (col)]
  111. #define BUFFER(col, row)  buffer[BUFFER_ROW (row) * num_cols + (col)]
  112. #define INCREASE(row)     (row = ROW (row + 1))
  113.  
  114. #define MAP_VALID        FALSE
  115. #define MAP_INVALID      TRUE
  116.  
  117. #define GET_CHARACTER(x)      (x).character
  118. #define GET_ATTRIBUTE(x)      (x).attribute
  119. #define GET_MAP(x)            (x).map
  120.  
  121. #define SET_CHARACTER(x, c)   (x).character = (c)
  122. #define SET_ATTRIBUTE(x, a)   (x).attribute = (a)
  123. #define SET_MAP(x, m)         (x).map = (m)
  124.  
  125. #ifndef Wimp_CloseDown /* hideous... */
  126. #define Wimp_CloseDown 0x400dd
  127. #endif
  128.  
  129. #define MAX(X,Y) ((X)>(Y)?(X):(Y))
  130. #define MIN(X,Y) ((X)<(Y)?(X):(Y))
  131.  
  132. #define NUM_VPIX   32
  133. #define NUM_HPIX   16
  134.  
  135. #define INPUT_BUFFER_SIZE 256
  136.  
  137. #define TASK_ID ('T'+('A'<<8)+('S'<<16)+('K'<<24))
  138.  
  139. /*****************************************************************************/
  140.  
  141. /* Buffer */
  142. typedef struct BUFFER_CELL {
  143.    char character, attribute, map, preserved;
  144. } BUFFER_CELL;
  145.  
  146. static BUFFER_CELL *buffer;
  147. static int buf_start, buf_end, buf_num_rows;
  148.  
  149. /* Input buffer */
  150. static int input_buffer[INPUT_BUFFER_SIZE];
  151. static int in_buf_end = 0, in_buf_next = 0;
  152.  
  153. /* Screen */
  154. static int scr_num_rows;
  155. static int cursor_col, cursor_row, cursor_on = FALSE, cursor_state,
  156.            cursor_interval, cursor_nexttime, cursor_type, real_cursor_on;
  157.  
  158. /* General & Wimp */
  159. static int num_cols, handle, num_hpix = NUM_HPIX, num_vpix = NUM_VPIX;
  160. static int update_pending = FALSE, extent_base = 0, screen_base = 0;
  161. static char *line;
  162. static int intch = -1;
  163.  
  164. /*****************************************************************************/
  165.  
  166. static int
  167. monotomic_time (void)
  168. {
  169.    art_reg_set r;
  170.  
  171.    (void) art_swix (0x42, &r);
  172.    return (r.r[0]);
  173. } /* monotomic_time */
  174.  
  175. /*****************************************************************************/
  176.  
  177. static void
  178. set_caret (void)
  179. {
  180.    art_reg_set r;
  181.  
  182.    r.r[0] = handle, r.r[1] = -1, r.r[2] = r.r[3] = r.r[5] = 0;
  183.    r.r[4] = 1 << 25;
  184.    (void) art_swix (Wimp_SetCaretPosition, &r);
  185. } /* set_caret */
  186.  
  187. /*****************************************************************************/
  188.  
  189. void
  190. text_closedown (void)
  191. {
  192.    art_reg_set r;
  193.  
  194.    (void) art_swix (Wimp_CloseDown, &r);
  195. } /* text_closedown */
  196.  
  197. /*****************************************************************************/
  198.  
  199. /* TEXT coordinates: (INCLUSIVE, EXCLUSIVE, EXCLUSIVE, INCLUSIVE) */
  200.  
  201. static void
  202. invalidate (int lx, int by, int rx, int ty)
  203. {
  204.    art_reg_set r;
  205.    int _lx = MAX (lx, 0),
  206.        _by = MIN (by, buf_num_rows),
  207.        _rx = MIN (rx, num_cols),
  208.        _ty = MAX (ty, 0);
  209.  
  210.    r.r[0] = handle;
  211.    r.r[1] = _lx * num_hpix;
  212.    r.r[2] = extent_base + screen_base -_by * num_vpix;
  213.    r.r[3] = _rx * num_hpix;
  214.    r.r[4] = extent_base + screen_base -_ty * num_vpix;
  215.  
  216.    (void) art_swix (Wimp_ForceRedraw, &r);
  217. } /* invalidate */
  218.  
  219. /*****************************************************************************/
  220.  
  221. void
  222. text_cursor (int type, int interval)
  223. {
  224.    if (!type) cursor_on = FALSE;
  225.    else {
  226.       cursor_on = TRUE;
  227.       real_cursor_on = FALSE;
  228.       cursor_type = type;                          /* 1 = block, 2 = line */
  229.       cursor_col = cursor_row = 0;
  230.       cursor_interval = interval;
  231.       cursor_nexttime = monotomic_time ();
  232.       cursor_state = TRUE;
  233.    }
  234. } /* text_cursor */
  235.  
  236. /*****************************************************************************/
  237.  
  238. void
  239. text_cursor_pos (int col, int row)
  240. {
  241.    if (cursor_on) {
  242.       if (real_cursor_on) {
  243.          invalidate (cursor_col, cursor_row + 1, cursor_col + 1, cursor_row);
  244.       }
  245.       cursor_col = col;
  246.       cursor_row = row;
  247.    }
  248. } /* text_cursor_pos */
  249.  
  250. /*****************************************************************************/
  251.  
  252. void
  253. supress_cursor (int set_it_off)      /* if !0 supress it */
  254. {
  255.    if (set_it_off) {
  256.       if (cursor_on) {
  257.          cursor_state = 0;
  258.          real_cursor_on = FALSE;
  259.          invalidate (cursor_col, cursor_row + 1, cursor_col + 1, cursor_row);
  260.       }
  261.    }
  262.    else real_cursor_on = cursor_on;
  263. }
  264.  
  265. /*****************************************************************************/
  266.  
  267.  
  268. typedef struct {int a[3]; } unfortunate_hack;
  269.  
  270. int
  271. text_init (int nc, int nr, int bufr, char *title, int inc, int inr, int ich)
  272. {
  273.    art_reg_set r;
  274.    art_open_block o;
  275.    art_wind_block t = {0, 0, 0, 0, 0, 0, -1, 0x1010f,
  276.                        {7,2,7,0,3,1,12}, 0, 0, -1024, 1280, 0, 0x27000139,
  277.                        0x3000, {0, 0}, {0,0,0,0,0,0,0,0,0,0,0,0}, 0};
  278.    int i;
  279.    unfortunate_hack *tit;
  280.  
  281.    tit = (unfortunate_hack *) &t.title[0];
  282.    tit->a[0] = (int) title;
  283.    tit->a[1] = (int) "";
  284.    tit->a[2] = 1 + strlen (title);
  285.  
  286.    intch = ich;
  287.    if (nc <= 0 || nr <= 0 || bufr < nr) return -1;
  288.    if ((buffer = calloc (nc * bufr, sizeof (BUFFER_CELL))) == NULL) return -1;
  289.    if ((line = malloc (nc + 1)) == NULL) goto ___;
  290.    for (i = 0; i < nc * bufr; i++) SET_CHARACTER (buffer[i], ' ');
  291.    scr_num_rows = nr, buf_num_rows = bufr, num_cols = nc;
  292.    buf_start = 0, buf_end = ROW (scr_num_rows);
  293.  
  294.    r.r[0] = 200, r.r[1] = TASK_ID, r.r[2] = (int) title;
  295.    if (art_swix (Wimp_Initialise, &r)) goto __;
  296.    r.r[1] = (int) &t;
  297.    t.exx0 = t.exy1 = 0, t.exx1 = num_hpix * nc, t.exy0 = -num_vpix * nr;
  298.    t.x0 = 640 - inc * num_hpix / 2, t.x1 = 1280 - t.x0;
  299.    t.y0 = 512 - inr * num_vpix / 2, t.y1 = 1024 - t.y0;
  300.    if (art_swix (Wimp_CreateWindow, &r)) goto __;
  301.    handle = r.r[0];
  302.  
  303.    o.wind_handle = handle, r.r[1] = (int) &o;
  304.    if (art_swix (Wimp_GetWindowState, &r) || art_swix (Wimp_OpenWindow, &r))
  305.       goto __;
  306.    set_caret ();
  307.    return 0;
  308. __:
  309.    free (line);
  310. ___:
  311.    free (buffer);
  312.    return -1;
  313. } /* text_init */
  314.  
  315. /*****************************************************************************/
  316.  
  317. int
  318. text_putch (char ch, int attr, int col, int row)
  319. {
  320.    if (col < 0 || col >= num_cols || row < 0 || row >= scr_num_rows)
  321.       return -1;
  322.    SET_CHARACTER (SCREEN (col, row), ch);
  323.    SET_ATTRIBUTE (SCREEN (col, row), attr);
  324.    SET_MAP (SCREEN (col, row), MAP_INVALID);
  325.    update_pending = TRUE;
  326.    return 0;
  327. } /* putch */
  328.  
  329. /*****************************************************************************/
  330.  
  331. static void
  332. redraw_window (art_redraw_block * b)
  333. {
  334.    int i, j, rem_x, rem_y;
  335.    int lx, by, rx, ty, clx, cby, crx, cty;
  336.    art_reg_set r;
  337.  
  338.    art_gcol (0,7);
  339.    r.r[1] = (int) b;
  340.    (void) art_swix (Wimp_RedrawWindow, &r);
  341.    while (r.r[0]) {
  342.       /* graphics coordinates in work-area-extent */
  343.       lx = b->scx + b->gx0 - b->x0; rx = lx + (b->gx1 - b->gx0);
  344.       by = b->scy + b->gy0 - b->y1 - extent_base; ty = by + (b->gy1 - b->gy0);
  345.       /* character coordinates in work-area-extent */
  346.       clx = lx / num_hpix, crx = 1 + rx / num_hpix;
  347.       if (crx > num_cols) crx = num_cols;
  348.       if (clx < 0) clx = 0;
  349.       cty = -ty / num_vpix; cby = 1 - (by / num_vpix);
  350.       for (j = cty; j < cby; j++) {
  351.          rem_x = b->gx0 - (lx%num_hpix);
  352.          rem_y = b->gy1 - (ty%num_vpix) - (j-cty) * num_vpix - num_vpix/8;
  353.          art_move (rem_x, rem_y);
  354.          for (i = clx; i < crx; i++) {
  355.             line[i - clx] = GET_CHARACTER (BUFFER (i, j));
  356.          }
  357.          line[i] = 0;
  358.          r.r[0] = (int) line;
  359.          (void) art_swix (OS_Write0, &r);
  360.          if (cursor_on && real_cursor_on && cursor_state && j == cursor_row
  361.              && cursor_col >= clx && cursor_col < crx) {
  362.             art_move (rem_x + (cursor_col-clx) * num_hpix,
  363.                       rem_y - num_vpix + num_vpix / 8);
  364.             art_gcol (4, 7);
  365.             if (cursor_type == 2) art_plot (1, num_hpix - 1, 0);
  366.             else if (cursor_type == 1) {
  367.                art_plot (97, num_hpix - 1, num_vpix - 1);
  368.             }
  369.             art_gcol (0, 7);
  370.          }
  371.       }
  372.       (void) art_swix (Wimp_GetRectangle, &r);
  373.    }
  374. } /* redraw_window */
  375.  
  376. /*****************************************************************************/
  377. /* Returns:    1 need to call text_update
  378.                0 normally
  379.               -1 if program should exit */
  380.  
  381. int
  382. text_poll (int immediate_exit)
  383. {
  384.    int i, f;
  385.    art_reg_set r;
  386.    int a[64];
  387.  
  388.    do {
  389.       r.r[0] = wimp_EMPTRENTER | wimp_EMPTRLEAVE
  390.                | wimp_EMUSERDRAG | wimp_EMMENU;
  391.       r.r[1] = (int) &a;
  392.  
  393. #ifdef NEVER
  394.       if (cursor_on) {
  395.          r.r[2] = cursor_nexttime;
  396.          (void) art_swix (0x400e1, &r);
  397.       }
  398.       else {
  399.          r.r[0] |= wimp_EMNULL;
  400. #endif
  401.  
  402.          (void) art_swix (Wimp_Poll, &r);
  403.  
  404. #ifdef NEVER
  405.       }
  406. #endif
  407.  
  408.       switch (f = r.r[0]) {
  409.       case 1: /* redraw */
  410.          if (*a == handle)
  411.             redraw_window ((art_redraw_block *) &a);
  412.          break;
  413.       case 2: /* open */
  414.          if (*a == handle)
  415.             (void) art_swix (Wimp_OpenWindow, &r);
  416.          break;
  417.       case 3: /* close */
  418.          if (*a == handle) {
  419.             (void) art_swix (Wimp_CloseDown, &r);
  420.             if (immediate_exit) exit (0);
  421.             else return -1;
  422.          }
  423.          break;
  424.       case 6: /* mouse click */
  425.          set_caret ();
  426.          break;
  427.       case 8: /* inkey */
  428.          if (a[6] == 0x1cc || a[6] == 0x1fc) {
  429.             /* F12 or <SHIFT><CTRL>F12 pressed */
  430.             r.r[0] = a[6];
  431.             (void) art_swix (0x400dc, &r);
  432.          }
  433.          else if (a[6] == intch) {
  434.             /* intch is the interrupt key. Set to -1 if not wanted */
  435.             in_buf_end = in_buf_next = 0;
  436.             raise (SIGINT);
  437.          }
  438.          else if ((i = (in_buf_end + 1) % INPUT_BUFFER_SIZE) != in_buf_next) {
  439.             in_buf_end = i;
  440.             input_buffer[in_buf_end] = a[6];
  441.          }
  442.          break;
  443.       case 10: /* scroll */
  444.          if (*a == handle) {
  445.             a[5] += ((a[8] == 1 || a[8] == -1) ? num_hpix * a[8]
  446.                      : ( a[8] == 0 ? 0 : (a[8] / 2 * (a[3] - a[1]))));
  447.             a[6] += ((a[9] == 1 || a[9] == -1) ? num_vpix * a[9]
  448.                      : ( a[9]  == 0 ? 0 : (a[9] / 2 * (a[4] - a[2]))));
  449.             (void) art_swix (Wimp_OpenWindow, &r);
  450.          }
  451.          break;
  452.       case 17: /* message */
  453.       case 18: /* message */
  454.          if (a[4] == 0) {
  455.             (void) art_swix (Wimp_CloseDown, &r);
  456.             if (immediate_exit) exit (0);
  457.             else return -1;
  458.          }
  459.          break;
  460.       default:
  461.          break;
  462.       }
  463.       if (cursor_on && real_cursor_on &&
  464.           monotomic_time () >= cursor_nexttime) {
  465.          cursor_state = !cursor_state;
  466.          cursor_nexttime = monotomic_time () + cursor_interval;
  467.          invalidate (cursor_col, cursor_row + 1, cursor_col + 1, cursor_row);
  468.       }
  469.    } while (f);
  470.    return (update_pending ? 1 : 0);
  471. } /* text_poll */
  472.  
  473. /*****************************************************************************/
  474.  
  475. int
  476. text_lookahead (void)
  477. {
  478.    if (in_buf_next == in_buf_end) return -1;
  479.    return input_buffer[(in_buf_next + 1) % INPUT_BUFFER_SIZE];
  480. } /* text_lookahead */
  481.  
  482. /*****************************************************************************/
  483.  
  484. int
  485. text_inkey (void)
  486. {
  487.    if (in_buf_next == in_buf_end) {
  488.       supress_cursor (0);
  489.       return -1;
  490.    }
  491.    in_buf_next = (in_buf_next + 1) % INPUT_BUFFER_SIZE;
  492.    supress_cursor (1);
  493.    return input_buffer[in_buf_next];
  494. } /* text_inkey */
  495.  
  496. /*****************************************************************************/
  497.  
  498. void
  499. text_update (void)
  500. {
  501.    int x, y, xl, xr;
  502.  
  503.    if (update_pending) {
  504.       for (y = 0; y < scr_num_rows; y++) {
  505.          x = 0;
  506.          for (;;) {
  507.             while ((x < num_cols) && (GET_MAP (SCREEN (x, y)) == MAP_VALID))
  508.                x++;
  509.             if (x >= num_cols) break;
  510.             xl = xr = x;
  511.             while (xr < num_cols && (GET_MAP (SCREEN (xr, y)) == MAP_INVALID)){
  512.                SET_MAP (SCREEN (xr, y), MAP_VALID);
  513.                xr++;
  514.             }
  515.             invalidate (xl, y + 1, xr, y);
  516.          }
  517.       }
  518.       update_pending = FALSE;
  519.    }
  520. } /* text_update */
  521.  
  522. /*****************************************************************************/
  523.  
  524. static void
  525. enlarge_extent (int dby, int dty)
  526. /* CALL ONLY WITH 0 OR -1 AS ARGUMENT VALUE!!! */
  527. {
  528.    art_reg_set r;
  529.    int b[30];
  530.  
  531.    b[0] = handle, r.r[1] = (int) &b;
  532.    (void) art_swix (Wimp_GetWindowInfo, &r);
  533.    b[12] += dby * num_vpix;
  534.    extent_base = (b[14] += dty * num_vpix);
  535.    screen_base -= ((dty == 0) ? num_vpix : 0);
  536.    r.r[0] = handle;
  537.    r.r[1] = (int) &b[11];
  538.    (void) art_swix (Wimp_SetExtent, &r);
  539. } /* enlarge_extent */
  540.  
  541. /*****************************************************************************/
  542.  
  543. void
  544. text_open_screen (void)
  545. {
  546.    art_reg_set r;
  547.    int b[30];
  548.  
  549.    b[0] = handle, r.r[1] = (int) &b;
  550.    (void) art_swix (Wimp_GetWindowInfo, &r);
  551.    b[6] = b[12] - scr_num_rows * num_vpix;
  552.    (void) art_swix (Wimp_OpenWindow, &r);
  553. } /* text_open_screen */
  554.  
  555. /*****************************************************************************/
  556.  
  557. void
  558. text_scroll (void)
  559. {
  560.    int x;
  561.    art_reg_set r;
  562.    int b[30];
  563.  
  564.    /* Remember current window information */
  565.    b[0] = handle, r.r[1] = (int) &b;
  566.    (void) art_swix (Wimp_GetWindowInfo, &r);
  567.  
  568.    if (buf_start == buf_end) {
  569.       INCREASE (buf_start);
  570.       INCREASE (buf_end);
  571.       enlarge_extent (-1, -1);
  572.       for (x = 0; x < num_cols; x++) {
  573.          SET_CHARACTER (SCREEN (x, scr_num_rows - 1), ' ');
  574.          SET_ATTRIBUTE (SCREEN (x, scr_num_rows - 1), 0);
  575.          SET_MAP (SCREEN (x, scr_num_rows - 1), MAP_INVALID);
  576.       }
  577.    } else {
  578.       INCREASE (buf_end);
  579.       enlarge_extent (-1, 0);
  580.    }
  581.  
  582.    if (b[6] + b[2] - b[4] < b[12] /*-b[14]*/ + num_vpix) {
  583.       text_open_screen ();
  584.    }
  585.    else if (b[6] - b[14] > -num_vpix) {
  586.       (void) art_swix (Wimp_GetWindowInfo, &r);
  587.       (void) art_swix (Wimp_OpenWindow, &r);
  588.    }
  589. } /* text_scroll */
  590. #endif
  591.